import 'package:backend.core/core/domain/entities/user_role.dart';
import 'package:backend.core/core/domain/helpers/verify_access_token.dart';
import 'package:backend.core/core/domain/utils/either_extension.dart';
import 'package:backend.core/core/infrastructure/helpers/request_helpers.dart';
import 'package:shelf/shelf.dart';

abstract class ForbidAdminAuthorization {
  Middleware call();
}

class ForbidAdminAuthorizationImpl implements ForbidAdminAuthorization {
  const ForbidAdminAuthorizationImpl({
    required VerifyAccessToken verifyAccessToken,
  }) : _verifyAccessToken = verifyAccessToken;

  final VerifyAccessToken _verifyAccessToken;

  @override
  Middleware call() {
    return (innerHandler) {
      return (request) async {
        var accessTokenClaim = maybeExtractAccessTokenClaim(
          request: request,
        );

        if (accessTokenClaim == null) {
          final accessTokenData = extractAccessTokenData(
            request: request,
          );

          if (accessTokenData != null) {
            final failureOrAccessTokenClaim = _verifyAccessToken(
              accessTokenData: accessTokenData,
            );

            if (failureOrAccessTokenClaim.isLeft()) {
              return Response(401);
            }

            accessTokenClaim = failureOrAccessTokenClaim.asRight();

            request = setAccessTokenClaim(
              request: request,
              accessTokenClaim: accessTokenClaim,
            );
          }
        }

        if (accessTokenClaim != null && accessTokenClaim.userRole.isAdmin) {
          return Response(403);
        }

        final response = await Future.sync(() {
          return innerHandler(request);
        });

        return response;
      };
    };
  }
}
